package com.zmn.oms.zmn.business.impl.work;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.zmn.base.common.data.common.dro.company.CompanyDRO;
import com.zmn.base.common.data.dubbo.interfaces.company.CompanyListRemoteService;
import com.zmn.base.engineer.common.dro.foreign.engineer.ForeignEngineerBasicInfoDRO;
import com.zmn.base.engineer.dubbo.interfaces.foreign.EngineerListRemoteService;
import com.zmn.base.product.common.consts.BaseProductConsts;
import com.zmn.base.product.common.dto.product.ProductBaseQuery;
import com.zmn.base.product.common.dto.product.ec.DefaultEcProductQuery;
import com.zmn.base.product.common.dto.product.ec.ProductBaseDRO;
import com.zmn.base.product.dubbo.interfaces.product.foreign.ProductForeignListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dictionary.DictModel;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.manager.mq.interfaces.ZmnMQSender;
import com.zmn.manager.redis.RedisManager;
import com.zmn.oms.business.interfaces.conf.channel.ConfOrderChannelBService;
import com.zmn.oms.business.interfaces.operator.OrderWorkOperatorBService;
import com.zmn.oms.common.annotation.OrderWorkCasOperate;
import com.zmn.oms.common.annotation.ZsNormalOrderWorkLog;
import com.zmn.oms.common.constant.*;
import com.zmn.oms.common.dro.conf.channel.ConfOrderChannelDRO;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.enums.ConfChannelReceivablesLimitEnum;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.utils.TimeUtils;
import com.zmn.oms.constant.MessageQueueTopicConstant;
import com.zmn.oms.model.bo.order.GridCompanyQueryBO;
import com.zmn.oms.model.dto.operator.OrderWorkOperatorDTO;
import com.zmn.oms.model.dto.order.GridCompanyInfoDTO;
import com.zmn.oms.model.dto.order.zmn.CheckManageCompanyDTO;
import com.zmn.oms.model.dto.queue.PerfStockWarningDTO;
import com.zmn.oms.model.dto.work.modify.must.OrderAssignDTO;
import com.zmn.oms.model.dto.work.modify.other.ZsRemarkDTO;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.work.OrderAssignVO;
import com.zmn.oms.services.interfaces.conf.workturn.biztype.PlatBizTypeService;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.interfaces.order.ZsOrderBService;
import com.zmn.oms.zmn.business.interfaces.statement.ZsOrderStatementBService;
import com.zmn.oms.zmn.business.interfaces.work.OrderWorkAssignBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkBService;
import com.zmn.oms.zmn.business.interfaces.work.customwork.ZsDistributeWorkBService;
import com.zmn.oms.zmn.normal.business.interfaces.order.ZsNormalOrderBService;
import com.zmn.sp.common.model.available.SpAvailableAreaCheckDIO;
import com.zmn.sp.common.model.manage.SpServProviderDRO;
import com.zmn.sp.common.model.manage.SpServProviderPaymentLimitDRO;
import com.zmn.sp.common.model.rule.ProductAndAddressDIO;
import com.zmn.sp.dubbo.interfaces.available.AvailableAreaListRemoteService;
import com.zmn.sp.dubbo.interfaces.manage.SpManageListRemoteService;
import com.zmn.sp.dubbo.interfaces.rule.ServiceRuleListRemoteService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.zmn.oms.common.constant.ChannelConsts.CHANNEL_ID_ASSIGN_VIRTUAL_COMANY_LIST;

/**
 * 类描述：工单分单 service
 * @author liuying
 * @date 2019/05/08 18:54
 */
@Service
public class OrderWorkAssignBServiceImpl implements OrderWorkAssignBService {

    protected org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    ZsOrderWorkBService zsOrderWorkBService;
    @Autowired
    ZsOrderStatementBService zsOrderStatementBService;
    @Autowired
    ZsNormalOrderBService zsNormalOrderBService;

    //@Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    //private BaseInfoListRemoteService baseInfoListRemoteService;

    @Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerListRemoteService engineerListRemoteService;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    private CompanyListRemoteService companyListRemoteService;

    @Reference(version = com.zmn.sp.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    private ServiceRuleListRemoteService serviceRuleListRemoteService;

    @Reference(version = com.zmn.sp.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    private AvailableAreaListRemoteService availableAreaListRemoteService;

    @Reference(version = com.zmn.sp.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    private SpManageListRemoteService spManageListRemoteService;
    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    private ProductForeignListRemoteService productForeignListRemoteService;

    @Resource
    private ConfOrderChannelBService confOrderChannelBService;

    @Resource
    private PlatBizTypeService platBizTypeService;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private OrderWorkService orderWorkService;

    @Autowired
    private OrderWorkAssignBService orderWorkAssignBService;

    @Autowired
    private ZsDistributeWorkBService zsDistributeWorkBService;

    @Autowired
    private OrderWorkOperatorBService orderWorkOperatorBService;
    @Autowired
    private ZsOrderBService zsOrderBService;

    @Resource
    private ZmnMQSender zmnMQSender;

    @Resource
    private RedisManager redisManager;

    @Override
    public List<OrderAssignVO> listAssignCompany(Long orderId, Long workId) {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderId);
        return this.listAssignCompany(orderWork, orderDetail, false);
    }

    @Override
    public List<OrderAssignVO> listAssignCompany(OrderWork orderWork, OrderDetail orderDetail, Boolean auto) {

        // 校验平台开通业务类型
        List<Integer> bizTypeList = platBizTypeService.listBizTypeByPlat(orderWork.getPlatWork());
        if (CollectionUtils.isEmpty(bizTypeList)) {
            this.saveDissatisfy(orderWork, null, OrderConsts.PRE_DISCONTENT_REASON_ONE, auto);
            return Lists.newArrayList();
        }
        if(!bizTypeList.contains(orderWork.getBizType())){
            this.saveDissatisfy(orderWork, null, OrderConsts.PRE_DISCONTENT_REASON_ONE, auto);
            return Lists.newArrayList();
        }

        // 检查平台是否开通服务分类
        boolean checkCategory = zsOrderWorkBService
                .checkOpenCategByPlatAndCateg(orderWork.getPlatWork(), orderWork.getServCategId(),
                        orderWork.getShowCategId());
        if (!checkCategory) {
            this.saveDissatisfy(orderWork, null, OrderConsts.PRE_DISCONTENT_REASON_TWO, auto);
            return Lists.newArrayList();
        }

        // 返修单-返回所属服务公司
        List<OrderAssignVO> reworkOrderAssignVOS = this.listReworkOrderAssignVO(orderWork, orderDetail);
        if (CollectionUtil.isNotNullOrEmpty(reworkOrderAssignVOS)) {
            return reworkOrderAssignVOS;
        }

        // 啄木鸟虚拟公司
        // 去掉啄木鸟特殊分单逻辑，代码注释，不删  wangxiaokun 20200908
        /*List<OrderAssignVO> zmnVirtualCompanyVoList = this.listZmnAssignVirtualCompanyVO(orderWork, orderDetail);
        if (CollectionUtils.isNotEmpty(zmnVirtualCompanyVoList)) {
            return zmnVirtualCompanyVoList;
        }*/

        // 可服务公司
        List<OrderAssignVO> orderAssignVOS = this.listCanServCompany(orderWork, orderDetail);
        if (CollectionUtil.isNullOrEmpty(orderAssignVOS)) {
            this.checkExis(null, orderAssignVOS, orderWork, orderDetail, null, auto);
            return orderAssignVOS;
        } else {
            this.checkExis(null, orderAssignVOS, orderWork, orderDetail, null, auto);
        }

        // 收款限制过滤
        List<OrderAssignVO> orderAssignVOS2 = this.listCanServCompanyFilterPaymentLimit(orderWork, orderAssignVOS);
        if (CollectionUtil.isNullOrEmpty(orderAssignVOS2)) {
            this.checkExis(orderAssignVOS, orderAssignVOS2, orderWork, null, OrderConsts.PRE_DISCONTENT_REASON_THREE, auto);
            return orderAssignVOS2;
        } else {
            this.checkExis(orderAssignVOS, orderAssignVOS2, orderWork, null, OrderConsts.PRE_DISCONTENT_REASON_THREE, auto);
        }

        return orderAssignVOS2;
    }

    /**
     * 检查服务商集合是否存在预分配服务商，如果不存在记录不满足原因
     * @param originalList 过滤前服务商列表
     * @param filterList 过滤后服务商列表
     * @param orderWork
     * @param orderDetail
     * @param reason
     */
    private void checkExis(List<OrderAssignVO> originalList, List<OrderAssignVO> filterList, OrderWork orderWork, OrderDetail orderDetail, String reason, Boolean auto){

        // 不是自动派单返回
        if (!auto) {
            return;
        }

        String redisKey = String.format(RedisKeyConsts.CHECK_MANAGE_COMPANY_KEY, orderWork.getWorkId());
        String redisValue = redisManager.get(redisKey);

        // 没有预分配服务商，直接返回
        if (StringUtil.isBlank(redisValue)) {
            return;
        }

        // 不是null，有预分配服务商
        String[] arr = redisValue.split("-");
        Integer preManageCompanyId = Integer.valueOf(arr[0]);

        // 是否检查
        boolean isCheck = false;
        // 原列表是空，则检查
        if (CollectionUtil.isNullOrEmpty(originalList)) {
            isCheck = true;
        } else {
            // 原列表不是空，包含预分配服务商才检查
            List<Integer> oriIds = originalList.stream().map(OrderAssignVO::getManageCompanyId).collect(Collectors.toList());

            if (oriIds.contains(preManageCompanyId)){
                isCheck = true;
            }
        }
        if (isCheck){
            List<Integer> ids = filterList.stream().map(OrderAssignVO::getManageCompanyId).collect(Collectors.toList());
            String reasonKey = String.format(RedisKeyConsts.CHECK_MANAGE_COMPANY_REASON_KEY, orderWork.getWorkId());

            if (!ids.contains(preManageCompanyId)) {
                // 如果服务公司列表没有预分配服务商，则调接口查询不能服务具体原因
                if (Objects.nonNull(orderDetail)){
                    do {
                        SpAvailableAreaCheckDIO spAvailableAreaCheckDIO = new SpAvailableAreaCheckDIO();
                        spAvailableAreaCheckDIO.setBizType(orderWork.getBizType());
                        spAvailableAreaCheckDIO.setManageCompanyId(preManageCompanyId);
                        spAvailableAreaCheckDIO.setShowProductId(orderWork.getShowProductId());
                        if (Objects.equals(orderDetail.getStreetSource(), OrderConsts.STREET_SOURCE_NONE) ||
                                Objects.equals(orderDetail.getStreetSource(), OrderConsts.STREET_SOURCE_DEFAULT)) {
                            spAvailableAreaCheckDIO.setStreetId(orderDetail.getStreetId());
                        } else {
                            spAvailableAreaCheckDIO.setStreetId(0);
                        }
                        spAvailableAreaCheckDIO.setLongitude(orderDetail.getLongitude());
                        spAvailableAreaCheckDIO.setLatitude(orderDetail.getLatitude());
                        spAvailableAreaCheckDIO.setCountyId(orderDetail.getCountyId());

                        logger.debug("#oms#checkSpAvailableArea# dio:{}", JSON.toJSONString(spAvailableAreaCheckDIO));
                        ResponseDTO<Boolean> response = availableAreaListRemoteService.checkSpAvailableArea(spAvailableAreaCheckDIO);
                        logger.debug("#oms#checkSpAvailableArea# dro:{}", JSON.toJSONString(response));
                        if (response.isSuccess() && !response.getData()){
                            reason = response.getMessage();
                        }
                    } while (false);
                }
                redisManager.setex(reasonKey, reason, 7 * 24 * 60 * 60);
                /*ZsRemarkDTO dto = new ZsRemarkDTO();
                dto.setOrderId(orderWork.getOrderId());
                dto.setWorkId(orderWork.getWorkId());
                dto.setOperator("系统");
                dto.setOperatorId(1L);
                dto.setRemark(arr[1] + "未自动分单缘由：" + reason);
                zsNormalOrderBService.saveWorkRemark(dto);*/
            } else {
                // 如果最后一项满足，则检查是否记录其他原因，有则删除
                if (Objects.equals(reason, OrderConsts.PRE_DISCONTENT_REASON_FIVE)
                        || Objects.equals(reason, OrderConsts.PRE_DISCONTENT_REASON_SIX)) {
                    String reasonValue = redisManager.get(reasonKey);
                    if (StringUtil.isNotBlank(reasonValue)) {
                        redisManager.del(reasonKey);
                    }
                }
            }
        }
    }

    /**
     * 记录不满足原因
     * @param orderWork
     * @param reason
     */
    @Override
    public void saveDissatisfy(OrderWork orderWork, List<OrderAssignVO> assignList, String reason, Boolean auto){
        String redisKey = String.format(RedisKeyConsts.CHECK_MANAGE_COMPANY_KEY, orderWork.getWorkId());
        String redisValue = redisManager.get(redisKey);
        if (StringUtil.isNotBlank(redisValue) && auto){
            String[] arr = redisValue.split("-");
            boolean flag = false;
            if (CollectionUtil.isNullOrEmpty(assignList)){
                flag = true;
            } else {
                if (!Objects.equals(assignList.get(0).getManageCompanyId(), Integer.valueOf(arr[0]))){
                    flag = true;
                }
            }
            if (flag){
                /*String reasonKey = String.format(RedisKeyConsts.CHECK_MANAGE_COMPANY_REASON_KEY, orderWork.getWorkId());
                redisManager.setex(reasonKey, reason, 7 * 24 * 60 * 60);*/
                ZsRemarkDTO dto = new ZsRemarkDTO();
                dto.setOrderId(orderWork.getOrderId());
                dto.setWorkId(orderWork.getWorkId());
                dto.setOperator("系统");
                dto.setOperatorId(1L);
                dto.setRemark(arr[1] + "未自动分单缘由：" + reason);
                zsNormalOrderBService.saveWorkRemark(dto);
            }
        }
    }

    /**
     * 过滤尾款限制公司
     * @param orderWork
     * @param orderAssignVOS
     * @return
     */
    public List<OrderAssignVO> listCanServCompanyFilterPaymentLimit(OrderWork orderWork,
                                                                    List<OrderAssignVO> orderAssignVOS) {
        if (CollectionUtil.isNullOrEmpty(orderAssignVOS)) {
            return orderAssignVOS;
        }
        List<Integer> manageCompanyIds = orderAssignVOS.stream().map(e -> e.getManageCompanyId())
                .collect(Collectors.toList());
        List<Integer> canServCompanyIds = this.listCanServCompanyFilterPaymentLimit(manageCompanyIds, orderWork.getChannelId(), orderWork.getBizType());

        // 过滤不收尾款的服务公司
        List<OrderAssignVO> newOrderAssignVOS = orderAssignVOS.stream()
                .filter(e -> canServCompanyIds.contains(e.getManageCompanyId())).collect(Collectors.toList());
        logger.debug("canServCompanyIds[{}]，newOrderAssignVOS[{}]", canServCompanyIds, newOrderAssignVOS);

        return newOrderAssignVOS;
    }

    /**
     * 通过尾款限制获取可服务公司
     * @param manageCompanyIds
     * @param channelId
     * @param bizType
     * @return
     */
    @Override
    public List<Integer> listCanServCompanyFilterPaymentLimit(List<Integer> manageCompanyIds,
                                                              Integer channelId,
                                                              Integer bizType) {
        if (CollectionUtil.isNullOrEmpty(manageCompanyIds)) {
            return manageCompanyIds;
        }

        logger.info("可分单服务公司-收款限制过滤前[{}]", manageCompanyIds);

        ConfOrderChannelDRO confOrderChannelDRO = null;
        try {
            confOrderChannelDRO = confOrderChannelBService.getByChannelId(channelId);
            logger.info("channelOrderConfigListRemoteService#getByChannelId入参[{}]，出参[{}]", channelId,
                    JSON.toJSONString(confOrderChannelDRO));
            if (Objects.isNull(confOrderChannelDRO)) {
                logger.info("服务商收款限制-未查到渠道[{}] ，接口[{}]", channelId, "ConfOrderChannelBService#getByChannelId");
                return manageCompanyIds;
            }
        } catch (OmsBaseException omsBaseException) {
            omsBaseException.printStackTrace();
        }

        // 渠道收尾款限制
        Integer restPaymentLimit;
        ConfOrderChannelDRO orderConfigData = confOrderChannelDRO;
        if (Objects.equals(bizType, com.zmn.consts.GlobalConsts.BIZ_TYPE_F)) {
            restPaymentLimit = orderConfigData.getInReceivablesLimit();
        } else {
            restPaymentLimit = orderConfigData.getOutReceivablesLimit();
        }
        if (NumberUtil.isNullOrZero(restPaymentLimit)) {
            logger.info("服务商收款限制-没配置尾款限制[{}]", restPaymentLimit);
            return manageCompanyIds;
        }

        logger.info("spManageListRemoteService#listBalancePaymentLimitByIds: 请求[{}]", manageCompanyIds);
        ResponseDTO<List<SpServProviderPaymentLimitDRO>> spServProviderPaymentLimitRemote = spManageListRemoteService.listBalancePaymentLimitByIds(manageCompanyIds);
        logger.info("spServProviderPaymentLimitRemote#listBalancePaymentLimitByIds 返回[{}]",
                JSON.toJSON(spServProviderPaymentLimitRemote));
        if (!spServProviderPaymentLimitRemote.isSuccess() || CollectionUtil
                .isNullOrEmpty(spServProviderPaymentLimitRemote.getData())) {
            logger.info("服务商收款限制-未查到服务公司的收款限制remote接口[{}]", spServProviderPaymentLimitRemote.getMessage());
            return manageCompanyIds;
        }

        // 工程师收款 或 预付+尾款
        List<Integer> collect = null;
        if (restPaymentLimit == ConfChannelReceivablesLimitEnum.CONSTS_GCS
                || restPaymentLimit == ConfChannelReceivablesLimitEnum.CONSTS_YFWK) {
            // 查询（收尾款或不收尾款） + 收尾款的服务公司
            collect = spServProviderPaymentLimitRemote.getData().stream()
                    .filter(e -> Objects.equals(3, e.getBalancePaymentLimit()) // 收尾款 + 不收尾款
                            || Objects.equals(1, e.getBalancePaymentLimit())) // 收尾款
                    .map(e -> e.getSpId()).collect(Collectors.toList());
        }
        // 下单预付全款 或 后付费
        else if (restPaymentLimit == ConfChannelReceivablesLimitEnum.CONSTS_XDYF
                || restPaymentLimit == ConfChannelReceivablesLimitEnum.CONSTS_HF) {
            // 查询（收尾款或不收尾款） + 不收尾款的服务公司
            collect = spServProviderPaymentLimitRemote.getData().stream()
                    .filter(e -> Objects.equals(3, e.getBalancePaymentLimit()) // 收尾款 + 不收尾款
                            || Objects.equals(2, e.getBalancePaymentLimit())) // 不收尾款
                    .map(e -> e.getSpId()).collect(Collectors.toList());
        }
        if (collect == null) {
            logger.info("服务商收款限制-未匹配的限制类型", restPaymentLimit);
            return manageCompanyIds;
        }

        logger.info("可分单服务公司-收款限制过滤后[{}]", collect);
        return collect;
    }

    /**
     * 获取可服务的公司
     * @param orderWork
     * @param orderDetail
     * @return
     */
    private List<OrderAssignVO> listCanServCompany(OrderWork orderWork, OrderDetail orderDetail) {
        // 下单公司是否可以服务
        List<OrderAssignVO> orderAssignVOList = listSaasOrderAssignVO(orderWork, orderDetail);
        if (CollectionUtils.isNotEmpty(orderAssignVOList)) {
            return orderAssignVOList;
        }

        List<OrderAssignVO> orderAssignVOS = listBaseAssignList(orderWork, orderDetail);

        // 言而有信虚拟公司
        List<OrderAssignVO> yeyxVirtualCompanyVoList = this.listYeyxAssignVirtualCompanyVO(orderWork, orderDetail);
        if (CollectionUtils.isNotEmpty(yeyxVirtualCompanyVoList)) {
            orderAssignVOS.addAll(yeyxVirtualCompanyVoList);
        }

        // 分单优先级 排序
        // 分单报错临时处理
        orderAssignVOS.forEach(e-> e.setSendOrderLevel(Optional.ofNullable(e.getSendOrderLevel()).orElse(0)));
        orderAssignVOS.sort(Comparator.comparing(OrderAssignVO::getSendOrderLevel));

        return orderAssignVOS;
    }

    @Override
    public void saveAssign(OrderAssignDTO orderAssignDTO) throws OmsBaseException {

        //保存分单
        orderWorkAssignBService.saveAssignEvent(orderAssignDTO);

        OrderWork dbOrderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderAssignDTO.getOrderId(), orderAssignDTO.getWorkId());

        // 分单，发送库存预警队列
        if (Objects.equals(OrderConsts.ORDER_TYPE_NEW, dbOrderWork.getType()) && NumberUtil.isNotNullOrZero(dbOrderWork.getManageCompanyId())) {
            if (TimeUtils.isCurDateRange(dbOrderWork.getDutyTime(), 14)) {
                PerfStockWarningDTO perfStockWarningDTO = PerfStockWarningDTO.builder()
                        .dutyDate(DateUtil.dateFormatToString(dbOrderWork.getDutyTime(), DateUtil.FORMAT_DEFAULT))
                        .cityId(dbOrderWork.getCityId())
                        .manageCompanyId(orderAssignDTO.getManageCompanyId())
                        .servCategId(dbOrderWork.getServCategId())
                        .showCategOneId(dbOrderWork.getShowCategOneId())
                        .showCategTwoId(dbOrderWork.getShowCategId())
                        .build();
                logger.info("分单-发送PERF库存预警队列[{}]", perfStockWarningDTO);
                String perfStockWarningJson = JSON.toJSONString(perfStockWarningDTO);
                String perfKey = String.valueOf(dbOrderWork.getWorkId());
                zmnMQSender.send(MessageQueueTopicConstant.ZMN_TOPIC_PERF, MessageQueueTagConsts.ZMN_PERF_STOCK_WARNING, perfKey, perfStockWarningJson);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @OrderWorkCasOperate(type = OrderConsts.ORDER_OP_TYPE_ASSIGN)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_ASSIGN, beforeProceed = false)
    public void saveAssignEvent(OrderAssignDTO orderAssignDTO) throws OmsBaseException {
        // 设置分单时间
        orderAssignDTO.setAssignDate(DateUtil.getNow());
        // 分单记录行政服务商
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setDetailId(orderAssignDTO.getOrderId());
        orderDetail.setGridCompanyId(orderAssignDTO.getCompanyId());
        orderDetail.setGridCompanyName(orderAssignDTO.getCompanyName());
        orderDetail.setGridManageCompanyId(orderAssignDTO.getManageCompanyId());
        orderDetail.setGridManageCompanyName(orderAssignDTO.getManageCompanyName());
        orderDetail.setUpdater(orderAssignDTO.getOperator());
        orderDetailService.updateOrderDetailByKey(orderDetail);
        this.saveAssignEventNoLog(orderAssignDTO);

        // 服务商派单冗余行政服务时组织架构
        OrderWorkOperatorDTO dto = BeanMapper.map(orderAssignDTO, OrderWorkOperatorDTO.class);
        orderWorkOperatorBService.insertOrUpdateOperator(dto);
    }

    @Override
    public void saveAssignEventNoLog(OrderAssignDTO orderAssignDTO) throws OmsBaseException {
        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(orderAssignDTO.getOrderId());
        updateOrderWork.setWorkId(orderAssignDTO.getWorkId());
        updateOrderWork.setStatus(OrderStatusConsts.WORK_STATUS_ASSIGN);
        updateOrderWork.setAssignerId(orderAssignDTO.getOperatorId());
        updateOrderWork.setAssignTime(orderAssignDTO.getAssignDate());
        updateOrderWork.setCompanyId(orderAssignDTO.getCompanyId());
        updateOrderWork.setManageCompanyId(orderAssignDTO.getManageCompanyId());

        // 获取公司信息
        ResponseDTO<CompanyDRO> companyResponseDTO = companyListRemoteService.getCompanyDROById(orderAssignDTO.getCompanyId());
        logger.info("保存分单获取公司信息出参[{}]", JSON.toJSONString(companyResponseDTO));
        if (!companyResponseDTO.isSuccess() || Objects.isNull(companyResponseDTO.getData())) {
            throw new OmsBaseException("子公司不存在");
        } else {
            CompanyDRO companyDRO = companyResponseDTO.getData();
            updateOrderWork.setCompanyName(companyDRO.getName());
            // 组织架构
            updateOrderWork.setOrgOneId(companyDRO.getPlat());
            updateOrderWork.setOrgTwoId(companyDRO.getOrgTwoId());
            updateOrderWork.setOrgThreeId(companyDRO.getOrgThrId());
            // 第四级是公司
            updateOrderWork.setOrgFourId(orderAssignDTO.getManageCompanyId());

            // 服务商派单需要冗余行政服务商的组织架构
            orderAssignDTO.setGridOrgOneId(updateOrderWork.getOrgOneId());
            orderAssignDTO.setGridOrgTwoId(updateOrderWork.getOrgTwoId());
            orderAssignDTO.setGridOrgThreeId(updateOrderWork.getOrgThreeId());
            orderAssignDTO.setGridOrgFourId(updateOrderWork.getOrgFourId());
        }

        ResponseDTO<CompanyDRO> manageCompanyResponseDTO = companyListRemoteService.getCompanyDROById(orderAssignDTO.getManageCompanyId());
        if (!manageCompanyResponseDTO.isSuccess() || Objects.isNull(manageCompanyResponseDTO.getData())) {
            throw new OmsBaseException("服务公司不存在");
        } else {
            String companyName = manageCompanyResponseDTO.getData().getName();
            Integer type = manageCompanyResponseDTO.getData().getChildType();
            updateOrderWork.setManageCompanyName(companyName);
            updateOrderWork.setManageCompanyType(type);
        }
        // 冗余服务商三级类型
        ResponseDTO<SpServProviderDRO> remoteSp = spManageListRemoteService.getServProviderById(orderAssignDTO.getManageCompanyId());
        logger.debug("spManageListRemoteService#getServProviderById入参[{}]出参[{}]", orderAssignDTO.getManageCompanyId(), JSON.toJSONString(remoteSp));
        if (remoteSp.isSuccess() && remoteSp.getData()!=null) {
            updateOrderWork.setManageCompanyThirdType(remoteSp.getData().getThirdType());
        }
        orderWorkService.updateOrderWorkAssign(updateOrderWork);

        // 分单至非家修匠公司(45111)：可结算时间为首次分单时间
        if (!Objects.equals(CompanyConsts.ZMN_JXJ_COMPANY_ID, orderAssignDTO.getCompanyId())) {
            OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(orderAssignDTO.getOrderId(), orderAssignDTO.getWorkId());
            zsOrderStatementBService.updateChannelStatementCanTime(orderAssignDTO.getOrderId(), orderAssignDTO.getWorkId(), dbOrderWork.getChannelId(), orderAssignDTO.getCompanyId());
        }

        // 记录未分单缘由
        /*String redisKey = String.format(RedisKeyConsts.CHECK_MANAGE_COMPANY_KEY, orderAssignDTO.getWorkId());
        String redisValue = redisManager.get(redisKey);
        if (Objects.nonNull(redisValue)){
            String[] arr = redisValue.split("-");
            if (!Objects.equals(Integer.valueOf(arr[0]), orderAssignDTO.getManageCompanyId())) {
                String reasonKey = String.format(RedisKeyConsts.CHECK_MANAGE_COMPANY_REASON_KEY, orderAssignDTO.getWorkId());
                String reasonValue = redisManager.get(reasonKey);
                if (Objects.nonNull(reasonValue)) {
                    orderAssignDTO.setOperatorRemark(orderAssignDTO.getOperatorRemark() + "\n" + arr[1] + "未分单缘由：" + reasonValue);
                }
            }
        }*/
    }

    /**
     * 返回返修单所属的服务公司
     * @param orderWork
     * @param orderDetail
     * @return
     */
    @Override
    public List<OrderAssignVO> listReworkOrderAssignVO(OrderWork orderWork, OrderDetail orderDetail) {
        if (!Objects.equals(OrderConsts.ORDER_TYPE_REWORK, orderWork.getType())) {
            return null;
        }

        OrderWork sourceOrderWork = orderWorkService
                .findOrderWorkByKeySrcMaster(orderWork.getReworkId(), orderWork.getReworkId());
        if (sourceOrderWork == null || NumberUtil.isNullOrZero(sourceOrderWork.getManageCompanyId())) {
            logger.error("[{}]返修单未找到服务公司[{}]", sourceOrderWork.getWorkId(), sourceOrderWork.getManageCompanyId());
            return null;
        }
        CompanyDRO manageCompany = companyListRemoteService.getCompanyDROById(sourceOrderWork.getManageCompanyId()).getData();
        if (manageCompany == null || !Objects.equals(manageCompany.getStatus(), GlobalConsts.YES)) {
            logger.error("[{}]返修单未找到服务公司[{}]或服务公司被禁用remote接口", sourceOrderWork.getWorkId(),
                    sourceOrderWork.getManageCompanyId());
            return null;
        }

        logger.debug("[{}]返修单对应原服务公司id[{}]，数据[{}]", orderWork.getWorkId(), sourceOrderWork.getManageCompanyId(),
                JSONObject.toJSONString(manageCompany));
        // 服务公司
        OrderAssignVO assignVO = OrderAssignVO.builder().companyId(sourceOrderWork.getCompanyId())
                .companyName(sourceOrderWork.getCompanyName()).manageCompanyId(sourceOrderWork.getManageCompanyId())
                .manageCompanyName(sourceOrderWork.getManageCompanyName()).build();
        return Lists.newArrayList(assignVO);
    }

    /**
     * 返回推荐工程师所属的服务公司
     * @param orderWork
     * @param orderDetail
     * @return
     */
    @Override
    public List<OrderAssignVO> listMasterRecommendOrderAssignVO(OrderWork orderWork, OrderDetail orderDetail) {
        // 加单工程师
        Long recommenderId = orderWork.getRecommenderId();
        if (NumberUtil.isNullOrZero(recommenderId) ||
                !Objects.equals(GlobalConsts.OPERATE_USER_TYPE_MASTER, orderWork.getRecommenderType())) {
            return null;
        }
        // todo fubiao
        logger.info("listMasterRecommendOrderAssignVO#getEngineerById 入参 [{}]",recommenderId.intValue());
        ForeignEngineerBasicInfoDRO engineerCompanyDRO = engineerListRemoteService.getEngineerById(recommenderId.intValue()).getData();
        logger.info("listMasterRecommendOrderAssignVO#getEngineerById 出参 [{}]",JSON.toJSONString(engineerCompanyDRO));
        if (engineerCompanyDRO == null) {
            logger.error("未找到加单工程师[{}]对应的服务公司", recommenderId);
            return null;
        }
        logger.debug("#oms#recommend#assign 查询工程师公司入参[{}]出参[{}]", recommenderId,
                JSONObject.toJSONString(engineerCompanyDRO));

        Integer mannageCompanyId = engineerCompanyDRO.getSpCompanyId();// 服务公司

        SpAvailableAreaCheckDIO spAvailableAreaCheckDIO = new SpAvailableAreaCheckDIO();
        spAvailableAreaCheckDIO.setBizType(orderWork.getBizType());
        spAvailableAreaCheckDIO.setManageCompanyId(mannageCompanyId);
        spAvailableAreaCheckDIO.setShowProductId(orderWork.getShowProductId());
        spAvailableAreaCheckDIO.setCountyId(orderDetail.getCountyId());
        if (Objects.equals(orderDetail.getStreetSource(), OrderConsts.STREET_SOURCE_NONE) ||
                Objects.equals(orderDetail.getStreetSource(), OrderConsts.STREET_SOURCE_DEFAULT)) {
            spAvailableAreaCheckDIO.setStreetId(orderDetail.getStreetId());
        } else {
            spAvailableAreaCheckDIO.setStreetId(0);
        }
        spAvailableAreaCheckDIO.setLongitude(orderDetail.getLongitude());
        spAvailableAreaCheckDIO.setLatitude(orderDetail.getLatitude());

        // F单支持无经纬度可分单，如果不是F单，没有经纬度直接返回，不需要再调接口
        if (!Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F) &&
                Objects.isNull(orderDetail.getLatitude()) && Objects.isNull(orderDetail.getLongitude())){
            logger.debug("#oms#recommend#assign 该订单不是F单并且没有经纬度直接返回");
            return null;
        }

        logger.debug("#oms#listMasterRecommendOrderAssignVO# dio:{}", JSON.toJSONString(spAvailableAreaCheckDIO));
        ResponseDTO<Boolean> response = availableAreaListRemoteService.checkSpAvailableArea(spAvailableAreaCheckDIO);
        logger.debug("#oms#listMasterRecommendOrderAssignVO# dro:{}", response);

        logger.debug("#oms#recommend#assign 判断此位置是否在此服务的服务范围内 出参：{}", response);
        if (!response.getData()) {
            return null;
        }
        CompanyDRO manageCompany = companyListRemoteService.getCompanyDROById(mannageCompanyId).getData();
        if (manageCompany == null) {
            logger.error("未找到加单工程师[{}]对应的服务公司[{}]", recommenderId, mannageCompanyId);
            return null;
        }
        logger.debug("#oms#recommend#assign 查询服务公司出参：{}", JSONObject.toJSONString(manageCompany));
        if (!Objects.equals(manageCompany.getPlat(), orderWork.getPlatWork())){
            logger.debug("#oms#recommend#assign 工程师所属服务公司的平台与工单做单平台不一致");
            return null;
        }
        CompanyDRO company = companyListRemoteService.getCompanyDROById(engineerCompanyDRO.getSubCompanyId()).getData();
        if (company == null) {
            logger.error("未找到加单工程师[{}]对应的子公司[{}]", recommenderId, engineerCompanyDRO.getSubCompanyId());
            return null;
        }
        logger.debug("#oms#recommend#assign 查询子公司出参：{}", JSONObject.toJSONString(company));

        // 服务公司
        OrderAssignVO assignVO = OrderAssignVO.builder().companyId(company.getCompanyId())
                .companyName(company.getName()).manageCompanyId(manageCompany.getCompanyId())
                .manageCompanyName(manageCompany.getName()).recommendMasterId(recommenderId.intValue()).build();
        return Lists.newArrayList(assignVO);
    }

    /**
     * 平台如果是服务商下单优先分配给该服务商
     * @param orderWork
     * @param orderDetail
     * @return
     */
    private List<OrderAssignVO> listSaasOrderAssignVO(OrderWork orderWork, OrderDetail orderDetail) {
        Integer manageCompanyId = orderWork.getManageCompanyId();
        if (NumberUtil.isNullOrZero(manageCompanyId)) {
            logger.error("#oms#saas#assign orderId:{} 下单公司不存在 ", orderWork.getWorkId());
            return null;
        }
        SpAvailableAreaCheckDIO spAvailableAreaCheckDIO = new SpAvailableAreaCheckDIO();
        spAvailableAreaCheckDIO.setBizType(orderWork.getBizType());
        spAvailableAreaCheckDIO.setManageCompanyId(manageCompanyId);
        spAvailableAreaCheckDIO.setShowProductId(orderWork.getShowProductId());
        spAvailableAreaCheckDIO.setCountyId(orderDetail.getCountyId());
        if (Objects.equals(orderDetail.getStreetSource(), OrderConsts.STREET_SOURCE_NONE) ||
                Objects.equals(orderDetail.getStreetSource(), OrderConsts.STREET_SOURCE_DEFAULT)) {
            spAvailableAreaCheckDIO.setStreetId(orderDetail.getStreetId());
        } else {
            spAvailableAreaCheckDIO.setStreetId(0);
        }
        spAvailableAreaCheckDIO.setLongitude(orderDetail.getLongitude());
        spAvailableAreaCheckDIO.setLatitude(orderDetail.getLatitude());

        // F单支持无经纬度可分单，如果不是F单，没有经纬度直接返回，不需要再调接口
        if (!Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F) &&
                Objects.isNull(orderDetail.getLatitude()) && Objects.isNull(orderDetail.getLongitude())){
            logger.debug("#oms#saas#assign 该订单不是F单并且没有经纬度直接返回");
            return null;
        } else {
            spAvailableAreaCheckDIO.setCountyId(orderDetail.getCountyId());
        }
        logger.debug("#oms#saas#assign 判断此位置是否在此服务的服务范围内 入参,spAvailableAreaCheckDIO:{}", JSON.toJSONString(spAvailableAreaCheckDIO));
        ResponseDTO<Boolean> response = availableAreaListRemoteService.checkSpAvailableArea(spAvailableAreaCheckDIO);
        logger.debug("#oms#saas#assign 判断此位置是否在此服务的服务范围内 出参：{}", response);
        if (!response.isSuccess() || !response.getData()) {
            return null;
        }

        // 获取子公司信息
        OrderAssignVO orderAssign = getOrderAssignVOByCompanyIdAndManageCompanyId(orderWork.getPlatWork(), manageCompanyId);
        return orderAssign != null ? Lists.newArrayList(orderAssign) : Lists.newArrayList();
    }

    /**
     * 获取符合规则的服务公司
     * @param orderWork
     * @param orderDetail
     * @return
     */
    private List<OrderAssignVO> listBaseAssignList(OrderWork orderWork, OrderDetail orderDetail) {

        List<OrderAssignVO> list = Lists.newArrayList();
        ProductAndAddressDIO productAndAddressDIO = new ProductAndAddressDIO();
        productAndAddressDIO.setPlat(orderWork.getPlatWork());
        productAndAddressDIO.setBizType(orderWork.getBizType());
        productAndAddressDIO.setShowProductId(orderWork.getShowProductId());
        productAndAddressDIO.setCountyId(orderDetail.getCountyId());
        if (Objects.equals(orderDetail.getStreetSource(), OrderConsts.STREET_SOURCE_NONE) ||
                Objects.equals(orderDetail.getStreetSource(), OrderConsts.STREET_SOURCE_DEFAULT)) {
            productAndAddressDIO.setStreetId(orderDetail.getStreetId());
        } else {
            productAndAddressDIO.setStreetId(0);
        }
        productAndAddressDIO.setLongitude(orderDetail.getLongitude());
        productAndAddressDIO.setLatitude(orderDetail.getLatitude());

        // F单支持无经纬度可分单，如果不是F单，没有经纬度直接返回，不需要再调接口
        if (!Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F) &&
                Objects.isNull(orderDetail.getLatitude()) && Objects.isNull(orderDetail.getLongitude())){
            logger.debug("#oms#assign#listBaseAssignList# 该订单不是F单并且没有经纬度直接返回");
            return list;
        }

        logger.debug("#oms#assign#listBaseAssignList# 入参：{}", JSON.toJSONString(productAndAddressDIO));
        ResponseDTO<List<com.zmn.sp.common.model.manage.SpServProviderDRO>> responseDTO = serviceRuleListRemoteService.listSpByProductAndAddress(productAndAddressDIO);
        logger.debug("#oms#assign#listBaseAssignList#{} 出参：{}", orderWork.getWorkId(), JSON.toJSONString(responseDTO));
        List<com.zmn.sp.common.model.manage.SpServProviderDRO> companyList = responseDTO.getData();
        if (CollectionUtils.isEmpty(companyList)) {
            return list;
        }

        companyList.forEach(item -> {
            // 口碑渠道--不分单给家修匠
            boolean isKbJxj = Objects.equals(ChannelConsts.CHANNEL_ID_KOUBEI, orderWork.getChannelId())
                    && Objects.equals(item.getSubCompanyId(), CompanyConsts.ZMN_JXJ_COMPANY_ID);
            if (isKbJxj) {
                return;
            }
            OrderAssignVO orderAssignVO = new OrderAssignVO();
            orderAssignVO.setPlat(item.getPlat());
            orderAssignVO.setCompanyId(item.getSubCompanyId());
            orderAssignVO.setCompanyName(item.getSubCompanyName());
            orderAssignVO.setManageCompanyId(item.getSpId());
            orderAssignVO.setManageCompanyName(item.getName());
            orderAssignVO.setType(item.getTwoType());
            orderAssignVO.setSendOrderLevel(item.getAssignOrderLevel());
            list.add(orderAssignVO);
        });
        return list;
    }

    /**
     * 获取啄木鸟-虚拟公司
     * @param orderWork
     * @param orderDetail
     * @return
     */
    @Override
    public List<OrderAssignVO> listZmnAssignVirtualCompanyVO(OrderWork orderWork, OrderDetail orderDetail) {
        if (!Objects.equals(orderWork.getPlatWork(), GlobalConsts.PLAT_MARK_ZMN)) {
            return Lists.newArrayList();
        }
        if (!CHANNEL_ID_ASSIGN_VIRTUAL_COMANY_LIST.contains(orderWork.getChannelId())) {
            return Lists.newArrayList();
        }

        OrderAssignVO virtualCompanyVO = getOrderAssignVOByCompanyIdAndManageCompanyId(orderWork.getPlat(), CompanyConsts.ZMN_VIRTUAL_MANAGE_COMPANY_ID);
        return virtualCompanyVO != null ? Lists.newArrayList(virtualCompanyVO) : Lists.newArrayList();
    }

    /**
     * 获取言而有信-虚拟公司
     * @param orderWork
     * @param orderDetail
     * @return
     */
    @Override
    public List<OrderAssignVO> listYeyxAssignVirtualCompanyVO(OrderWork orderWork, OrderDetail orderDetail) {
        if (!Objects.equals(orderWork.getPlatWork(), GlobalConsts.PLAT_MARK_YEYX)) {
            return Lists.newArrayList();
        }
        ResponseDTO<SpServProviderDRO> responseDTO = spManageListRemoteService.getServProviderById(CompanyConsts.YEYX_VIRTUAL_MANAGE_COMPANY_ID);

        logger.debug("#oms#listAssignVirtualCompanyList#assign 查询服务公司出参：{}", JSONObject.toJSONString(responseDTO));
        if (!responseDTO.isSuccess() || Objects.isNull(responseDTO.getData())) {
            logger.error("未找到服务公司[{}]", CompanyConsts.YEYX_VIRTUAL_MANAGE_COMPANY_ID);
            return Lists.newArrayList();
        }
        SpServProviderDRO spServProviderDRO = responseDTO.getData();
        ResponseDTO<CompanyDRO> companyByCompanyResponse = companyListRemoteService.getCompanyDROById(CompanyConsts.YEYX_VIRTUAL_MANAGE_COMPANY_ID);
        if (companyByCompanyResponse.getData() == null) {
            logger.error("未找到服务公司[{}]", CompanyConsts.YEYX_VIRTUAL_MANAGE_COMPANY_ID);
            return null;
        }
        CompanyDRO company = companyByCompanyResponse.getData();
        // 分单VO
        OrderAssignVO assignVO = OrderAssignVO.builder().plat(orderWork.getPlatWork()).companyId(company.getSubCompanyId())
                .companyName(company.getSubCompanyName()).manageCompanyId(spServProviderDRO.getSpId())
                .manageCompanyName(spServProviderDRO.getName()).type(spServProviderDRO.getType())
                .sendOrderLevel(spServProviderDRO.getAssignOrderLevel()).build();
        return Lists.newArrayList(assignVO);
    }

    private OrderAssignVO getOrderAssignVOByCompanyIdAndManageCompanyId(Integer plat,
                                                                        Integer manageCompanyId) {
        ResponseDTO<SpServProviderDRO> responseDTO = spManageListRemoteService.getServProviderById(manageCompanyId);
        logger.debug("#oms#listAssignVirtualCompanyList#assign 查询服务公司出参：{}", JSONObject.toJSONString(responseDTO));
        if (!responseDTO.isSuccess() || Objects.isNull(responseDTO.getData())) {
            logger.error("未找到服务公司[{}]", manageCompanyId);
            return null;
        }
        SpServProviderDRO spServProviderDRO = responseDTO.getData();
        // 分单VO
        OrderAssignVO assignVO = OrderAssignVO.builder().plat(plat).companyId(spServProviderDRO.getSubCompanyId())
                .companyName(spServProviderDRO.getSubCompanyName()).manageCompanyId(spServProviderDRO.getSpId())
                .manageCompanyName(spServProviderDRO.getName()).type(spServProviderDRO.getType())
                .sendOrderLevel(spServProviderDRO.getAssignOrderLevel()).build();
        return assignVO;
    }

    /**
     * 服务商最高优先级列表
     * @param list
     * @return
     */
    private List<OrderAssignVO> listZmnAssignList(List<OrderAssignVO> list){
        // 已有服务商的优先级
        Set<Integer> level = list.stream().map(OrderAssignVO::getSendOrderLevel).collect(Collectors.toSet());

        // 服务商按优先级分组转为Map
        Map<Integer, List<OrderAssignVO>> map = list.stream()
                .collect(Collectors.groupingBy(OrderAssignVO::getSendOrderLevel));

        // 取出每一项优先级的服务商列表
        return map.get(level.iterator().next());
    }

    /**
     * 获取优先分单列表
     * @param list
     * @return
     */
    @Override
    public List<OrderAssignVO> listZmnPriorityAssignList(List<OrderAssignVO> list, OrderWork orderWork, OrderDetail orderDetail) {

        // 服务商最高优先级列表
        List<OrderAssignVO> orderAssignVOS = this.listZmnAssignList(list);

        if (Objects.nonNull(orderWork)){
            this.checkExis(list, orderAssignVOS, orderWork, null, OrderConsts.PRE_DISCONTENT_REASON_FIVE, true);
        }

        if (orderAssignVOS.size() == 1){
            return orderAssignVOS;
        } else {

            if (Objects.isNull(orderWork)){
                return list;
            }
            Integer cityId = orderWork.getCityId();
            // 直营服务商
            List<OrderAssignVO> orderAssignDirect = orderAssignVOS.stream().filter(vo -> Objects.equals(vo.getType(),
                    com.zmn.base.plat.engine.common.constant.CompanyConsts.COMPANY_TYPE_SERVICE_OCO))
                    .collect(Collectors.toList());
            // 非直营服务商
            List<OrderAssignVO> orderAssignNotDirect = orderAssignVOS.stream().filter(vo -> Objects.equals(vo.getType(),
                    com.zmn.base.plat.engine.common.constant.CompanyConsts.COMPANY_TYPE_SERVICE_NOT_OCO))
                    .collect(Collectors.toList());

            //只有一个直营公司多个非直营公司才计算配比
            if (CollectionUtil.isNotNullOrEmpty(orderAssignDirect) && orderAssignDirect.size() == 1
                    && CollectionUtil.isNotNullOrEmpty(orderAssignNotDirect)){

                OrderAssignVO directAssgin = orderAssignDirect.get(0);
                directAssgin.setProportion(GlobalConsts.NO);
                Integer directManagerCompanyId = directAssgin.getManageCompanyId();
                Random random = new Random();
                OrderAssignVO notDirectAssgin = orderAssignNotDirect.get(random.nextInt(orderAssignNotDirect.size()));
                notDirectAssgin.setProportion(GlobalConsts.NO);
                Integer notDirectManagerCompanyId = notDirectAssgin.getManageCompanyId();

                // 当天直营服务商分单量
                int todayDirectCount = 0;
                String todayDirectKey = String.format(RedisKeyConsts.AUTO_ASSIGN_DIRECT_DATE_CITY_KEY,
                        DateUtil.getNowFormatted(DateUtil.FORMAT_DATE2), cityId, directManagerCompanyId, notDirectManagerCompanyId);
                String todayDirectValue = redisManager.get(todayDirectKey);

                if (StringUtil.isNotBlank(todayDirectValue)){
                    todayDirectCount = Integer.valueOf(todayDirectValue);
                }

                // 当天非直营服务商分单量
                int todayNotDirectCount = 0;
                String todayNotDirectKey = String.format(RedisKeyConsts.AUTO_ASSIGN_NOT_DIRECT_DATE_CITY_KEY,
                        DateUtil.getNowFormatted(DateUtil.FORMAT_DATE2), cityId, directManagerCompanyId, notDirectManagerCompanyId);
                String todayNotDirectValue = redisManager.get(todayNotDirectKey);
                if (StringUtil.isNotBlank(todayNotDirectValue)){
                    todayNotDirectCount = Integer.valueOf(todayNotDirectValue);
                }

                // 计算过期时间，明天凌晨1点过期
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(new Date());
                calendar.add(Calendar.DAY_OF_MONTH, 1);
                calendar.set(Calendar.HOUR_OF_DAY, 1);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                int seconds = (int) DateUtil.getTimespan(calendar.getTime(), DateUtil.UNIT_SECOND);

                // 信息公司和非信息公司服务商当天分单比例为：3比1
                // 预先分配非直营
                int preNotDirectCount = ++todayNotDirectCount * 3;
                // 如果非直营单量乘以3大于直营单量，则优先分配给直营，否则分配给非直营
                boolean direct = false;
                String redisKey = todayNotDirectKey;
                String manageCompanyName = notDirectAssgin.getManageCompanyName();
                if (preNotDirectCount > todayDirectCount){
                    redisKey = todayDirectKey;
                    direct = true;
                    manageCompanyName = directAssgin.getManageCompanyName();
                }

                // 如果key存在则自动加1，不存在则赋值并设置过期时间
                if (redisManager.exists(redisKey)){
                    redisManager.incr(redisKey);
                } else {
                    redisManager.incr(redisKey);
                    redisManager.expire(redisKey, seconds);
                }

                logger.info("【自动分单】[配比3:1]城市:{}-直营:{}-{}-当前单量:{}/非直营:{}-{}-当前单量:{}。订单号:{}，通过配比分给:{}",
                        orderDetail.getCityName(), directAssgin.getManageCompanyId(),
                        directAssgin.getManageCompanyName(), todayDirectCount, notDirectAssgin.getManageCompanyId(),
                        notDirectAssgin.getManageCompanyName(), --todayNotDirectCount, orderWork.getOrderId(),
                        manageCompanyName);

                List<OrderAssignVO> resultList = Lists.newArrayListWithCapacity(1);
                // true分配给直营服务商，false随机分配非直营服务商
                if (direct){
                    resultList.add(directAssgin);
//                    return Lists.newArrayList(directAssgin);
                } else {
                    resultList.add(notDirectAssgin);
//                    return Lists.newArrayList(notDirectAssgin);
                }

                // 检查是否有预分配服务商
                this.checkExis(orderAssignVOS, resultList, orderWork, null, OrderConsts.PRE_DISCONTENT_REASON_SIX, true);

                return resultList;
            }
            return list;
        }

        /*// 优先等级依次往下
        // 信息公司
        List<OrderAssignVO> infoAssignList = list.stream()
                .filter(assignVO -> Objects.equals(assignVO.getType(), com.zmn.base.plat.engine.common.constant.CompanyConsts.COMPANY_TYPE_SERVICE_OCO))
                .collect(Collectors.toList());
        if (infoAssignList.size() == 1) {
            return infoAssignList;
        } else if (infoAssignList.size() > 1) {
            return list;
        }

        // 非家修匠服务商
        List<OrderAssignVO> spAssignList = list.stream()
                .filter(assignVO -> Objects.equals(assignVO.getType(), com.zmn.base.plat.engine.common.constant.CompanyConsts.COMPANY_TYPE_SERVICE_THIRD)
                        && !Objects.equals(assignVO.getCompanyId(), com.zmn.oms.common.constant.CompanyConsts.ZMN_JXJ_COMPANY_ID))
                .collect(Collectors.toList());
        if (spAssignList.size() == 1) {
            return spAssignList;
        } else if (spAssignList.size() > 1) {
            return list;
        }

        // 非家修匠众包商
        List<OrderAssignVO> zbAssignList = list.stream()
                .filter(assignVO -> Objects.equals(assignVO.getType(), com.zmn.base.plat.engine.common.constant.CompanyConsts.COMPANY_TYPE_SERVICE_CCO)
                        && !Objects.equals(assignVO.getCompanyId(), com.zmn.oms.common.constant.CompanyConsts.ZMN_JXJ_COMPANY_ID))
                .collect(Collectors.toList());
        if (zbAssignList.size() == 1) {
            return zbAssignList;
        } else if (zbAssignList.size() > 1) {
            return list;
        }

        // 家修匠非特殊服务商和众包商
        List<OrderAssignVO> bnSpAssignList = list.stream()
                .filter(assignVO -> Objects.equals(assignVO.getCompanyId(), com.zmn.oms.common.constant.CompanyConsts.ZMN_JXJ_COMPANY_ID)
                        && (!Objects.equals(assignVO.getManageCompanyId(), com.zmn.oms.common.constant.CompanyConsts.ZMN_JXJ_SPECIAL_SERVICE_MANAGE_COMPANY_ID)
                        && !Objects.equals(assignVO.getManageCompanyId(), com.zmn.oms.common.constant.CompanyConsts.ZMN_JXJ_SPECIAL_SERVICE_MANAGE_COMPANY_ID2))
                ).collect(Collectors.toList());
        if (bnSpAssignList.size() == 1) {
            return bnSpAssignList;
        } else if (bnSpAssignList.size() > 1) {
            return list;
        }

        // 家修匠特殊服务商
        List<OrderAssignVO> bnSpecialAssignList = list.stream()
                .filter(assignVO -> Objects.equals(assignVO.getManageCompanyId(), com.zmn.oms.common.constant.CompanyConsts.ZMN_JXJ_SPECIAL_SERVICE_MANAGE_COMPANY_ID))
                .collect(Collectors.toList());
        if (bnSpecialAssignList.size() == 1) {
            return bnSpecialAssignList;
        } else if (bnSpecialAssignList.size() > 1) {
            return list;
        }

        // 家修匠特殊众包商
        List<OrderAssignVO> bnSpecialCrowdsourcingAssignList = list.stream()
                .filter(assignVO -> Objects.equals(assignVO.getManageCompanyId(), com.zmn.oms.common.constant.CompanyConsts.ZMN_JXJ_SPECIAL_SERVICE_MANAGE_COMPANY_ID2))
                .collect(Collectors.toList());
        if (bnSpecialCrowdsourcingAssignList.size() == 1) {
            return bnSpecialCrowdsourcingAssignList;
        } else {
            return list;
        }*/
    }

    /**
     * 获取言而有信平台分单优先级
     * @param list
     * @return
     */
    @Override
    public List<OrderAssignVO> listYeyxPriorityAssignList(List<OrderAssignVO> list, OrderWork orderWork) {

        // 已有服务商的优先级
        Set<Integer> level = list.stream().map(OrderAssignVO::getSendOrderLevel).collect(Collectors.toSet());

        // 服务商按优先级分组转为Map
        Map<Integer, List<OrderAssignVO>> map = list.stream()
                .collect(Collectors.groupingBy(OrderAssignVO::getSendOrderLevel));

        // 取出每一项优先级的服务商列表
        List<OrderAssignVO> orderAssignVOS = map.get(level.iterator().next());

        if (Objects.nonNull(orderWork)){
            this.checkExis(list, orderAssignVOS, orderWork, null, OrderConsts.PRE_DISCONTENT_REASON_FIVE, true);
        }

        if (orderAssignVOS.size() == 1){
            return orderAssignVOS;
        } else {
            return list;
        }

        /*// 优先等级依次往下
        // 非特殊服务商的普通服务商
        List<OrderAssignVO> infoAssignList = list.stream()
                .filter(assignVO ->
                        !Objects.equals(assignVO.getManageCompanyId(), com.zmn.oms.common.constant.CompanyConsts.YEYX_SPECIAL_MANAGE_COMPANY_ID)
                        && !Objects.equals(assignVO.getManageCompanyId(), com.zmn.oms.common.constant.CompanyConsts.YEYX_SPECIAL_MANAGE_COMPANY_ID2)
                )
                .collect(Collectors.toList());
        if (infoAssignList.size() == 1) {
            return infoAssignList;
        } else if (infoAssignList.size() > 1) {
            return list;
        }

        // 特殊服务商
        List<OrderAssignVO> specialAssignList = list.stream()
                .filter(assignVO -> Objects.equals(assignVO.getManageCompanyId(), com.zmn.oms.common.constant.CompanyConsts.YEYX_SPECIAL_MANAGE_COMPANY_ID))
                .collect(Collectors.toList());
        if (specialAssignList.size() == 1) {
            return specialAssignList;
        } else if (specialAssignList.size() > 1) {
            return list;
        }

        // 特殊服务商2
        List<OrderAssignVO> specialAssignList2 = list.stream()
                .filter(assignVO -> Objects.equals(assignVO.getManageCompanyId(), com.zmn.oms.common.constant.CompanyConsts.YEYX_SPECIAL_MANAGE_COMPANY_ID2))
                .collect(Collectors.toList());
        if (specialAssignList2.size() == 1) {
            return specialAssignList2;
        } else {
            return list;
        }*/
    }

    /**
     * 获取川南环保平台分单优先级
     * @param list
     * @return
     */
    @Override
    public List<OrderAssignVO> listCnhbPriorityAssignList(List<OrderAssignVO> list, OrderWork orderWork) {

        // 已有服务商的优先级
        Set<Integer> level = list.stream().map(OrderAssignVO::getSendOrderLevel).collect(Collectors.toSet());

        // 服务商按优先级分组转为Map
        Map<Integer, List<OrderAssignVO>> map = list.stream()
                .collect(Collectors.groupingBy(OrderAssignVO::getSendOrderLevel));

        // 取出每一项优先级的服务商列表
        List<OrderAssignVO> orderAssignVOS = map.get(level.iterator().next());

        if (Objects.nonNull(orderWork)){
            this.checkExis(list, orderAssignVOS, orderWork, null, OrderConsts.PRE_DISCONTENT_REASON_FIVE, true);
        }

        if (orderAssignVOS.size() == 1){
            return orderAssignVOS;
        } else {
            return list;
        }

        /*// 优先等级依次往下
        // 非指定特殊公司优先
        List<OrderAssignVO> unSpecialInfoAssignList = list.stream()
                .filter(e -> !Objects.equals(e.getManageCompanyId(), com.zmn.oms.common.constant.CompanyConsts.CNHB_SPECIAL_MANAGE_COMPANY_ID))
                .collect(Collectors.toList());
        if (unSpecialInfoAssignList.size() == 1) {
            return unSpecialInfoAssignList;
        } else {
            return list;
        }*/
    }

    /**
     * 校验服务商
     * @param dto
     * @return
     */
    @Override
    public ResultDTO checkManageCompany(CheckManageCompanyDTO dto) {

        OrderWork orderWork = BeanMapper.map(dto, OrderWork.class);
        OrderDetail orderDetail = BeanMapper.map(dto, OrderDetail.class);

        // 校验平台开通业务类型
        List<Integer> bizTypeList = platBizTypeService.listBizTypeByPlat(orderWork.getPlatWork());
        if(CollectionUtils.isEmpty(bizTypeList) || !bizTypeList.contains(orderWork.getBizType())){
            return ResultDTO.fail(OrderConsts.PRE_DISCONTENT_REASON_ONE);
        }

        // 检查平台是否开通服务分类
        boolean checkCategory = zsOrderWorkBService
                .checkOpenCategByPlatAndCateg(orderWork.getPlatWork(), orderWork.getServCategId(),
                        orderWork.getShowCategId());
        if (!checkCategory) {
            return ResultDTO.fail(OrderConsts.PRE_DISCONTENT_REASON_TWO);
        }

        List<OrderAssignVO> assignList;

        // 工程师加单
        assignList = this.listMasterRecommendOrderAssignVO(orderWork, orderDetail);
        if (CollectionUtil.isNotNullOrEmpty(assignList)){
            if (!Objects.equals(assignList.get(0).getManageCompanyId(), dto.getPreManageCompanyId())){
                return ResultDTO.fail(OrderConsts.PRE_DISCONTENT_REASON_EIGHT);
            }
            return ResultDTO.success(GlobalConsts.NO);
        }

        boolean flag = false;
        // 获取可服务公司
        assignList = this.listCanServCompany(orderWork, orderDetail);
        if (CollectionUtil.isNullOrEmpty(assignList)){
            flag = true;
        } else {
            List<Integer> manageCompanyIds = assignList.stream().map(OrderAssignVO::getManageCompanyId).collect(Collectors.toList());
            if (!manageCompanyIds.contains(dto.getPreManageCompanyId())){
                flag = true;
            }
        }
        // 如果服务公司列表没有预分配服务商，则调接口查询不能服务具体原因
        if (flag){
            SpAvailableAreaCheckDIO spAvailableAreaCheckDIO = new SpAvailableAreaCheckDIO();
            spAvailableAreaCheckDIO.setBizType(orderWork.getBizType());
            spAvailableAreaCheckDIO.setManageCompanyId(dto.getPreManageCompanyId());
            spAvailableAreaCheckDIO.setShowProductId(orderWork.getShowProductId());
            if (Objects.equals(orderDetail.getStreetSource(), OrderConsts.STREET_SOURCE_NONE) ||
                    Objects.equals(orderDetail.getStreetSource(), OrderConsts.STREET_SOURCE_DEFAULT)) {
                spAvailableAreaCheckDIO.setStreetId(orderDetail.getStreetId());
            } else {
                spAvailableAreaCheckDIO.setStreetId(0);
            }
            spAvailableAreaCheckDIO.setLongitude(orderDetail.getLongitude());
            spAvailableAreaCheckDIO.setLatitude(orderDetail.getLatitude());
            spAvailableAreaCheckDIO.setCountyId(orderDetail.getCountyId());

            logger.debug("#oms#checkSpAvailableArea# dio:{}", JSON.toJSONString(spAvailableAreaCheckDIO));
            ResponseDTO<Boolean> response = availableAreaListRemoteService.checkSpAvailableArea(spAvailableAreaCheckDIO);
            logger.debug("#oms#checkSpAvailableArea# dro:{}", JSON.toJSONString(response));
            if (response.isSuccess() && !response.getData()){
                return ResultDTO.fail(response.getMessage());
            }
        }

        // 收款限制过滤
        assignList = this.listCanServCompanyFilterPaymentLimit(orderWork, assignList);
        if (CollectionUtil.isNullOrEmpty(assignList)){
            return ResultDTO.fail(OrderConsts.PRE_DISCONTENT_REASON_THREE);
        } else {
            List<Integer> manageCompanyIds = assignList.stream().map(OrderAssignVO::getManageCompanyId).collect(Collectors.toList());
            if (!manageCompanyIds.contains(dto.getPreManageCompanyId())){
                return ResultDTO.fail(OrderConsts.PRE_DISCONTENT_REASON_THREE);
            }
        }

        // 优先级
        boolean priority = false;
        // 自动分单配比
        boolean proportion = false;

        do {
            // 多个服务商满足
            if (assignList.size() > 1){
                if (Objects.equals(orderWork.getPlatWork(), GlobalConsts.PLAT_MARK_ZMN)) {
                    assignList = this.listZmnAssignList(assignList);
                    List<Integer> zmnManageCompanyIds = assignList.stream().map(OrderAssignVO::getManageCompanyId).collect(Collectors.toList());
                    if (!zmnManageCompanyIds.contains(dto.getPreManageCompanyId())){
                        priority = true;
                        break;
                        //return ResultDTO.fail(OrderConsts.PRE_DISCONTENT_REASON_FIVE);
                    }
                    if (assignList.size() > 1){
                        Integer cityId = orderWork.getCityId();
                        // 直营服务商
                        List<OrderAssignVO> orderAssignDirect = assignList.stream().filter(vo -> Objects.equals(vo.getType(),
                                com.zmn.base.plat.engine.common.constant.CompanyConsts.COMPANY_TYPE_SERVICE_OCO))
                                .collect(Collectors.toList());
                        // 非直营服务商
                        List<OrderAssignVO> orderAssignNotDirect = assignList.stream().filter(vo -> Objects.equals(vo.getType(),
                                com.zmn.base.plat.engine.common.constant.CompanyConsts.COMPANY_TYPE_SERVICE_NOT_OCO))
                                .collect(Collectors.toList());

                        //只有一个直营公司多个非直营公司才计算配比
                        if (CollectionUtil.isNotNullOrEmpty(orderAssignDirect) && orderAssignDirect.size() == 1
                                && CollectionUtil.isNotNullOrEmpty(orderAssignNotDirect)) {

                            List<OrderAssignVO> list = Lists.newArrayListWithCapacity(1);

                            OrderAssignVO directAssgin = orderAssignDirect.get(0);
                            directAssgin.setProportion(GlobalConsts.NO);
                            Integer directManagerCompanyId = directAssgin.getManageCompanyId();
                            Random random = new Random();
                            OrderAssignVO notDirectAssgin = orderAssignNotDirect.get(random.nextInt(orderAssignNotDirect.size()));
                            notDirectAssgin.setProportion(GlobalConsts.NO);
                            Integer notDirectManagerCompanyId = notDirectAssgin.getManageCompanyId();

                            // 当天直营服务商分单量
                            int todayDirectCount = 0;
                            String todayDirectKey = String.format(RedisKeyConsts.AUTO_ASSIGN_DIRECT_DATE_CITY_KEY,
                                    DateUtil.getNowFormatted(DateUtil.FORMAT_DATE2), cityId, directManagerCompanyId, notDirectManagerCompanyId);
                            String todayDirectValue = redisManager.get(todayDirectKey);

                            if (StringUtil.isNotBlank(todayDirectValue)) {
                                todayDirectCount = Integer.valueOf(todayDirectValue);
                            }

                            // 当天非直营服务商分单量
                            int todayNotDirectCount = 0;
                            String todayNotDirectKey = String.format(RedisKeyConsts.AUTO_ASSIGN_NOT_DIRECT_DATE_CITY_KEY,
                                    DateUtil.getNowFormatted(DateUtil.FORMAT_DATE2), cityId, directManagerCompanyId, notDirectManagerCompanyId);
                            String todayNotDirectValue = redisManager.get(todayNotDirectKey);
                            if (StringUtil.isNotBlank(todayNotDirectValue)) {
                                todayNotDirectCount = Integer.valueOf(todayNotDirectValue);
                            }

                            // 信息公司和非信息公司服务商当天分单比例为：3比1
                            // 预先分配非直营
                            int preNotDirectCount = ++todayNotDirectCount * 3;
                            // 如果非直营单量乘以3大于直营单量，则优先分配给直营，否则分配给非直营
                            if (preNotDirectCount > todayDirectCount){
                                list.add(directAssgin);
                            } else {
                                list.add(notDirectAssgin);
                            }
                            if (!Objects.equals(list.get(0).getManageCompanyId(), dto.getPreManageCompanyId())){
                                proportion = true;
                                break;
                                //return ResultDTO.fail(OrderConsts.PRE_DISCONTENT_REASON_SIX);
                            } else {
                                return ResultDTO.success(GlobalConsts.NO);
                            }
                        }
                    }
                } else if (Objects.equals(orderWork.getPlatWork(), GlobalConsts.PLAT_MARK_YEYX)) {
                    // 优先列表
                    assignList = this.listYeyxPriorityAssignList(assignList, null);
                    List<Integer> yeyxManageCompanyIds = assignList.stream().map(OrderAssignVO::getManageCompanyId).collect(Collectors.toList());
                    if (!yeyxManageCompanyIds.contains(dto.getPreManageCompanyId())){
                        priority = true;
                        break;
                        //return ResultDTO.fail(OrderConsts.PRE_DISCONTENT_REASON_FIVE);
                    }
                } else if (Objects.equals(orderWork.getPlatWork(), GlobalConsts.PLAT_MARK_CNHB)) {
                    // 优先列表
                    assignList = this.listCnhbPriorityAssignList(assignList, null);
                    List<Integer> cnhbManageCompanyIds = assignList.stream().map(OrderAssignVO::getManageCompanyId).collect(Collectors.toList());
                    if (!cnhbManageCompanyIds.contains(dto.getPreManageCompanyId())){
                        priority = true;
                        break;
                        //return ResultDTO.fail(OrderConsts.PRE_DISCONTENT_REASON_FIVE);
                    }
                }
            }
        } while (false);


        // 再次判断服务商数量
        if (assignList.size() == 1 && Objects.equals(assignList.get(0).getManageCompanyId(), dto.getPreManageCompanyId())){
            // 自动分单满足
            return ResultDTO.success(GlobalConsts.NO);
        }

        List<OrderAssignVO> manualAssignList = this.listAssignCompany(orderWork, orderDetail, false);
        List<Integer> manualManageCompanyIds = manualAssignList.stream().map(OrderAssignVO::getManageCompanyId).collect(Collectors.toList());

        // 如果优先级或配比不满足，先校验人工分单是否满足
        if (priority || proportion){
            if (manualManageCompanyIds.contains(dto.getPreManageCompanyId())){
                // 手动分单满足
                return  ResultDTO.success(GlobalConsts.YES);
            }

            // 优先级不满足
            if (priority){
                return ResultDTO.fail(OrderConsts.PRE_DISCONTENT_REASON_FIVE);
            }

            // 分单配比不满足
            if (proportion){
                return ResultDTO.fail(OrderConsts.PRE_DISCONTENT_REASON_SIX);
            }
        }

        // 最后判断手动分单满不满足
        if (manualManageCompanyIds.contains(dto.getPreManageCompanyId())){
            // 手动分单满足
            return  ResultDTO.success(GlobalConsts.YES);
        }

        return ResultDTO.success();
    }

    /**
     * 校验服务能力
     * @param dto
     * @return
     */
    @Override
    public Boolean checkServiceCapacity(CheckManageCompanyDTO dto) {
        // 产品为空或0，直接返回false
        if (NumberUtil.isNullOrZero(dto.getProductId())) {
            return false;
        }

        OrderWork orderWork = BeanMapper.map(dto, OrderWork.class);
        orderWork.setManageCompanyId(0);
        OrderDetail orderDetail = BeanMapper.map(dto, OrderDetail.class);

        // 获取产品信息
        ProductBaseQuery productDIO = new ProductBaseQuery();
        productDIO.setProductId(orderWork.getProductId());
        com.zmn.common.dto2.ResponseDTO<List<ProductBaseDRO>> productRemote = productForeignListRemoteService.listBaseDROByQuery(productDIO);
        if (logger.isDebugEnabled()) {
            logger.debug("#获取产品接口productListRemoteService#listBaseDROByDIO#入参[{}],出参[{}]", productDIO, productRemote);
        }
        List<ProductBaseDRO> servProductDROS = productRemote.getData();
        if (CollectionUtil.isNullOrEmpty(servProductDROS)) {
            logger.error("[{}]产品不存在", orderWork.getProductId());
            return false;
        }

        ProductBaseDRO productBaseDRO = servProductDROS.get(0);
        if (Objects.equals(productBaseDRO.getShowType(), BaseProductConsts.EC_SHOW_TYPE)) {
            orderWork.setShowProductId(productBaseDRO.getProductId());
            orderWork.setServCategId(productBaseDRO.getServCategId());
            orderWork.setShowCategId(productBaseDRO.getCategId());
            orderWork.setShowCategOneId(productBaseDRO.getCategOneId());
        } else {
            // 后端产品找前端产品
            DefaultEcProductQuery defaultEcProductQuery = new DefaultEcProductQuery();
            defaultEcProductQuery.setProductIdList(Lists.newArrayList(productBaseDRO.getProductId()));
            defaultEcProductQuery.setShowType(BaseProductConsts.EC_SHOW_TYPE);
            com.zmn.common.dto2.ResponseDTO<List<ProductBaseDRO>> showProductRemote = productForeignListRemoteService.listEcErpProductByQuery(defaultEcProductQuery);
            if (!showProductRemote.isSuccess() || CollectionUtil.isNullOrEmpty(showProductRemote.getData())) {
                logger.error("后端产品[{}]未找到前端产品", orderWork.getProductId());
                return false;
            }
            ProductBaseDRO dro = showProductRemote.getData().get(0);

            orderWork.setShowProductId(dro.getProductId());
            orderWork.setServCategId(dro.getServCategId());
            orderWork.setShowCategId(dro.getCategId());
            orderWork.setShowCategOneId(dro.getCategOneId());
        }

        // 是否平台直派
        boolean isGrid = zsDistributeWorkBService.isGridDistributeByConfig(orderWork);
        if (isGrid) {
            // 不校验网格直接返回true
            if (!Objects.equals(dto.getCheckGrid(), com.zmn.consts.GlobalConsts.YES)) {
                return true;
            }

            GridCompanyQueryBO gridCompanyQueryBO = new GridCompanyQueryBO();
            gridCompanyQueryBO.setCityId(orderWork.getCityId());
            gridCompanyQueryBO.setDistributeWay(OrderDistributeConsts.DISTRIBUTE_WAY_PLAT);
            gridCompanyQueryBO.setLatitude(orderDetail.getLatitude());
            gridCompanyQueryBO.setLongitude(orderDetail.getLongitude());
            gridCompanyQueryBO.setServCategId(orderWork.getServCategId());
            gridCompanyQueryBO.setShowCategId(orderWork.getShowCategId());
            gridCompanyQueryBO.setShowCategOneId(orderWork.getShowCategOneId());
            gridCompanyQueryBO.setPlatWork(orderWork.getPlatWork());
            gridCompanyQueryBO.setOrderId(orderWork.getOrderId());
            GridCompanyInfoDTO gridCompanyInfo = zsOrderBService.getGridCompanyInfo(gridCompanyQueryBO);
            if (logger.isDebugEnabled()) {
                logger.debug("[{}]-处理行政子公司/服务商结果：【{}】", orderWork.getOrderId(), JSON.toJSONString(gridCompanyInfo));
            }

            // 无网格
            if (NumberUtil.isNullOrZero(gridCompanyInfo.getGridId())) {
                return false;
            }

            // 无法承接线索
            if (Objects.equals(gridCompanyInfo.getGridManageCompanyId(), CompanyConsts.ZMN_JXJ_MANAGE_COMPANY_ID)
                    || Objects.equals(gridCompanyInfo.getGridManageCompanyId(), CompanyConsts.ZMN_UNABLE_SERVICE_MANAGE_COMPANY_ID)) {
                return false;
            }

            return true;
        }

        // 工程师加单，返回加单工程师所属公司
        List<OrderAssignVO> orderAssignVOS = this.listMasterRecommendOrderAssignVO(orderWork, orderDetail);
        if (CollectionUtil.isNotNullOrEmpty(orderAssignVOS)) {
            return true;
        }

        // 查询所有平台可服务公司
        Integer platWork = orderWork.getPlatWork();
        orderWork.setPlatWork(null);
        orderAssignVOS = this.listCanServCompany(orderWork, orderDetail);
        if (CollectionUtil.isNullOrEmpty(orderAssignVOS)) {
            return false;
        }
        orderWork.setPlatWork(platWork);

        Map<Integer, List<OrderAssignVO>> map = orderAssignVOS.stream().collect(Collectors.groupingBy(OrderAssignVO::getPlat));
        logger.debug("校验服务商-全平台服务商：[{}]", JSON.toJSONString(map));

        // 检查当前平台
        boolean currentPlat = this.checkCurrentPlat(orderWork, map);
        if (currentPlat) {
            return true;
        }
        return false;
        // 检查其他平台
        //return this.checkOtherPlat(orderWork, map);

    }

    /**
     * 查询当前平台是否可服务
     * @param orderWork
     * @param map
     * @return
     */
    private boolean checkCurrentPlat(OrderWork orderWork, Map<Integer, List<OrderAssignVO>> map){
        // 校验平台开通业务类型
        List<Integer> bizTypeList = platBizTypeService.listBizTypeByPlat(orderWork.getPlatWork());
        if(CollectionUtils.isEmpty(bizTypeList) || !bizTypeList.contains(orderWork.getBizType())){
            return false;
        }

        // 检查平台是否开通服务分类
        boolean checkCategory = zsOrderWorkBService
                .checkOpenCategByPlatAndCateg(orderWork.getPlatWork(), orderWork.getServCategId(),
                        orderWork.getShowCategId());
        if (!checkCategory) {
            return false;
        }

        List<OrderAssignVO> list = map.get(orderWork.getPlatWork());
        logger.debug("校验服务商-当前平台服务商：[{}]", JSON.toJSONString(list));
        if (CollectionUtil.isNullOrEmpty(list)) {
            return false;
        }

        // 收款限制过滤
        list = this.listCanServCompanyFilterPaymentLimit(orderWork, list);
        logger.debug("校验服务商-当前平台服务商收款限制后：[{}]", JSON.toJSONString(list));
        if (CollectionUtil.isNullOrEmpty(list)) {
            return false;
        }

        return true;

    }

    /**
     * 查询其他平台是否可服务
     * @param orderWork
     * @param map
     * @return
     */
    private boolean checkOtherPlat(OrderWork orderWork, Map<Integer, List<OrderAssignVO>> map){
        // 查询其他平台可服务公司
        List<DictModel> otherPlatList = GlobalConsts.getPlatList().stream().filter(e -> !Objects.equals(e.getKey(), orderWork.getPlatWork())).collect(Collectors.toList());
        for (DictModel dictModel : otherPlatList) {

            // 校验平台开通业务类型
            List<Integer> bizTypeList = platBizTypeService.listBizTypeByPlat(dictModel.getKey());
            if (CollectionUtils.isEmpty(bizTypeList)) {
                continue;
            }
            if(!bizTypeList.contains(orderWork.getBizType())){
                continue;
            }

            // 检查其他平台是否开通服务分类
            boolean otherCheckCategory = zsOrderWorkBService.checkOpenCategByPlatAndCateg(dictModel.getKey(), orderWork.getServCategId(), orderWork.getShowCategId());
            if (!otherCheckCategory) {
                continue;
            }

            List<OrderAssignVO> list = map.get(dictModel.getKey());
            logger.debug("校验服务商-其他平台服务商：[{}]", JSON.toJSONString(list));
            if (CollectionUtil.isNullOrEmpty(list)) {
                continue;
            }

            // 收款限制过滤
            list = this.listCanServCompanyFilterPaymentLimit(orderWork, list);
            logger.debug("校验服务商-其他平台服务商收款限制后：[{}]", JSON.toJSONString(list));
            if (CollectionUtil.isNullOrEmpty(list)) {
                continue;
            }

            return true;
        }

        return false;
    }
}
